package yerr

import (
	"fmt"
)

var _ error = (*YErr)(nil)

func NewError(code ErrCode, msg string) *YErr {
	return &YErr{
		code: code,
		msg:  msg,
	}
}

func New(code ErrCode) *YErr {
	return NewError(code, "")
}

type YErr struct {
	code ErrCode
	msg  string
	err  error
}

func (y YErr) Code() ErrCode { return y.code }
func (y YErr) CodeInt() int  { return int(y.code) }
func (y YErr) Msg() string   { return y.msg }
func (y *YErr) WithMsg(msg string, args ...interface{}) *YErr {
	y.msg = y.msg + "|" + fmt.Sprintf(msg, args...)
	return y
}
func (y *YErr) WithCode(code ErrCode) *YErr { y.code = code; return y }
func (y *YErr) WithErr(err error) *YErr {
	if y.err == nil {
		y.err = err
	} else {
		y.err = fmt.Errorf("%s / %w", y.Error(), err)
	}
	return y
}

func (y *YErr) Error() string {
	errmsg := fmt.Sprintf("[%d]", y.code)
	errmsg += y.msg
	if y.err != nil {
		errmsg += " | "
		errmsg += y.err.Error()
	}
	return errmsg
}
